
// nb: check 29a-8.009 for details

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char** argv)
{
  FILE*f;
  static unsigned char buf[8192];
  int len,i;
  unsigned long start_off,a,b,*p;

  if (argc != 2)
  {
    printf("syntax: richdump infile.exe/dll\n");
    exit(0);
  }

  //printf("+ reading file: %s\n", argv[1]);

  /* read file */
  f = fopen(argv[1],"rb");
  assert(f);
  len = fread(buf,1,sizeof(buf),f);
  fclose(f);

  /* check MZ */
  assert(len >= 128 && buf[0] == 0x4D && buf[1] == 0x5A);

  /* find where info begins */

  p = (unsigned long*)&buf[start_off = 0];
  for(i = 0; (i*4+4) < len; i++)
    if ((p[i] ^ p[i+1]) == 0x536e6144/*DanS*/)
    {
      p = (unsigned long*)&buf[start_off = i*4];
      break;
    }

  /* dump */
  //printf("+ start_off = %08x\n", start_off);

  assert((p[0] ^ p[1]) == 0x536e6144/*DanS*/);

  for(i = 4; start_off+i*4+4 < len; i++)
  {
    if (p[i] == 0x68636952/*Rich*/) break;
    if (p[i] == 0x00004550/*PE\0\0*/) break;
    if (i&1) continue;

    a = p[i] ^ p[1];
    b = p[i+1] ^ p[1];

    printf("%08x %3d.%-3d %5d   %d\n",
      a,
      (a>>8)&255,
      a&255,
      a>>16,
      b);
  }

  exit(0);
  return 0;
} /* main() */

/* EOF */
